package com.whfc.fmam.service.impl;

import com.whfc.common.exception.BizException;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.SignUtil;
import com.whfc.fmam.dao.FmamApiTokenMapper;
import com.whfc.fmam.dao.FmamLicenseMapper;
import com.whfc.fmam.dao.FmamWeighRoomMapper;
import com.whfc.fmam.entity.bo.FmamApiToken;
import com.whfc.fmam.entity.bo.FmamLicense;
import com.whfc.fmam.entity.bo.FmamWeighRoom;
import com.whfc.fmam.entity.dto.FmamAccessTokenDTO;
import com.whfc.fmam.entity.dto.FmamClientDTO;
import com.whfc.fmam.entity.enums.ActiveFlag;
import com.whfc.fmam.entity.enums.ExpireFlag;
import com.whfc.fmam.entity.qo.AccessTokenQO;
import com.whfc.fmam.service.FmamApiTokenService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.UUID;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/10/16 9:08
 */
@DubboService(interfaceClass = FmamApiTokenService.class, version = "1.0.0")
public class FmamApiTokenServiceImpl implements FmamApiTokenService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final long TOKEN_EXPIRES_IN_SECONDS = 24 * 3600;

    private static final long SIGN_EXPIRES_IN_MILLS = 10 * 60 * 1000;

    @Autowired
    private FmamLicenseMapper fmamLicenseMapper;

    @Autowired
    private FmamApiTokenMapper fmamApiTokenMapper;

    @Autowired
    private FmamWeighRoomMapper fmamWeighRoomMapper;

    @Override
    public FmamAccessTokenDTO getAccessTokenDTO(AccessTokenQO accessTokenQO) throws BizException {

        String appId = accessTokenQO.getAppId();
        String sign = accessTokenQO.getSign();
        Long timestamp = accessTokenQO.getTimestamp();
        String randomStr = accessTokenQO.getRandomStr();
        String diskSn = accessTokenQO.getDiskSn();
        String mac = accessTokenQO.getMac();

        //验证身份
        FmamLicense license = fmamLicenseMapper.selectByAppId(appId);
        if (license == null) {
            throw new BizException(ResultEnum.NOT_FOUND.getCode(), "appId不正确");
        }
        if (ActiveFlag.INACTIVE.getValue().equals(license.getActiveFlag())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "授权文件尚未激活");
        }

        //验证签名
        if (System.currentTimeMillis() - timestamp > SIGN_EXPIRES_IN_MILLS) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "签名timestamp已过期");
        }

        //注意:此处兼容性处理(如果客户端读不到磁盘编号和网卡mac,则使用默认的参数参与签名,并上传相关参数)
        diskSn = StringUtils.isEmpty(diskSn) ? license.getDiskSn() : diskSn;
        mac = StringUtils.isEmpty(mac) ? license.getMac() : mac;

        String appKey = license.getAppKey();
        String calSign = SignUtil.sign(appId, diskSn, mac, timestamp, randomStr, appKey);
        logger.info("sign:[{}],calSign:[{}]", sign, calSign);
        if (!sign.equalsIgnoreCase(calSign)) {
            //todo 暂时关闭签名限制.
            logger.error("sign不正确");
            //throw new BizException(ResultEnum.FAILURE.getCode(), "sign不正确");
        }

        //生成accessToken
        Integer weighRoomId = license.getWeighRoomId();
        String accessToken = UUID.randomUUID().toString().replace("-", "");
        Date now = new Date();
        long expiresIn = TOKEN_EXPIRES_IN_SECONDS;
        Date exiresTime = new Date(now.getTime() + TOKEN_EXPIRES_IN_SECONDS * 1000);
        FmamApiToken apiToken = new FmamApiToken();
        apiToken.setWeighRoomId(weighRoomId);
        apiToken.setAccessToken(accessToken);
        apiToken.setExpiresIn(expiresIn);
        apiToken.setExpireTime(exiresTime);
        apiToken.setCreateTime(now);
        fmamApiTokenMapper.insertSelective(apiToken);

        //返回值
        FmamAccessTokenDTO tokenDTO = new FmamAccessTokenDTO();
        tokenDTO.setAccessToken(accessToken);
        tokenDTO.setCreateTime(now);
        tokenDTO.setExpireIn(expiresIn);
        return tokenDTO;
    }

    @Override
    public FmamClientDTO validateAccessToken(String accessToken) throws BizException {

        FmamApiToken apiToken = fmamApiTokenMapper.selectByAccessToken(accessToken);
        if (apiToken == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "accessToken无效");
        }
        if (ExpireFlag.EXPIRED.getValue().equals(apiToken.getExpireFlag()) ||
                System.currentTimeMillis() > apiToken.getExpireTime().getTime()) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "accessToken已过期");
        }

        Integer weighRoomId = apiToken.getWeighRoomId();
        FmamWeighRoom room = fmamWeighRoomMapper.selectByPrimaryKey(weighRoomId);
        if (room == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "磅房不存在");
        }

        FmamClientDTO fmamClientDTO = new FmamClientDTO();
        fmamClientDTO.setWeighRoomId(weighRoomId);
        fmamClientDTO.setDeptId(room.getDeptId());
        fmamClientDTO.setWeighRoomCode(room.getCode());
        fmamClientDTO.setWeighRoomName(room.getName());
        return fmamClientDTO;
    }
}
